import { Memory } from "./Memory";
import { Register } from "./Register";

export class Cpu {
    register: Register;
    memory: Memory;
    //堆栈计数器
    private spCount: number;
    constructor() {
        this.spCount = 0;
        this.register = new Register();
        this.memory = new Memory();
    }

    push(value: number): boolean {
        if (this.spCount > 256) {
            return false;
        }
        this.memory.write(this.register.getSP(), value);
        this.spCount++;
        return this.register.decSP();
    }

    pop(): number {
        if (this.spCount < 0) {
            return undefined;
        }
        let result = this.memory.read(this.register.getSP());
        this.register.incPC();
        this.spCount--;
        return result;
    }

    reset() {
        this.memory.reset();
        this.register.reset();
    }
    CLV() {
        this.register.STATUS.setV(false);
    }

    SEV() {
        this.register.STATUS.setV(true);
    }
    SEC() {
        this.register.STATUS.setC(true);
    }
    CLC() {
        this.register.STATUS.setC(false);
    }
    //求补码
    complement(value: number): number {
        return 0x100 - value;
    }

    nearJump(addr: number): void {
        if (addr > 0x7f) {
            //补码转原码得到相对跳转地址
            addr = 0x100 - addr;
            this.register.setPC(this.register.getPC() - addr);
            return;
        }
        this.register.setPC(this.register.getPC() + addr);
    }


    pipeline(): void {
        //地址
        let addr: number = 0;
        //数据1
        let d1: number = 0;
        //数据2
        let d2: number = 0;
        //结果
        let result: number = 0;
        //寄存器A
        let regA: number = 0;
        //状态C
        let statusC: number = 0;
        while (true) {

            switch (this.memory.read(this.register.getPC())) {
                //adc imm  带进位加法 立即数寻址方式
                case 0x69:
                    // PC 寄存器加1
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    statusC = this.register.STATUS.getC();
                    regA = this.register.getA();
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                // adc 零页寻址求和
                case 0x65:
                    this.register.incPC();
                    //得到零页寻址的地址
                    addr = this.memory.read(this.register.getPC());
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                //adc 零页x寄存器变址寻址
                case 0x75:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //得到零页变址寄存器X寻址的地址
                    addr = this.memory.read(this.register.getPC() + this.register.getX());
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                //adc 绝对寻址
                case 0x6d:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //得到16位绝对真实地址，其中高位地址存储数值的高位 6502处理器采用的是小端存储模式即10进制数值的个位在内存的低地址位当中。
                    addr = this.memory.readWord(this.register.nextPC());
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                //绝对变址X型
                case 0x7d:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //得到16位绝对真实地址，其中高位地址存储数值的高位 6502处理器采用的是小端存储模式即10进制数值的个位在内存的低地址位当中。
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getX();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                //绝对变址Y型
                case 0x79:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //得到16位绝对真实地址，其中高位地址存储数值的高位 6502处理器采用的是小端存储模式即10进制数值的个位在内存的低地址位当中。
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getY();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                //Adc 变址间接型寻址  X寄存器
                case 0x61:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    addr = this.memory.zpgReadWord(addr);
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                // ADC 间接变址型 Y寄存器寻址
                case 0x71:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //获得真实地址
                    addr = this.memory.read(this.register.getPC());
                    addr = this.memory.zpgReadWord(addr) + this.register.getY();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                //clc 此时c=0
                case 0x18:
                    this.register.STATUS.setC(false);
                    this.register.incPC();
                    break;
                //sec 此时c=1
                case 0x38:
                    this.register.STATUS.setC(true);
                    this.register.incPC();
                    break;
                //INC oper 零页寻址
                case 0xe6:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.read(this.register.getPC());
                    //零页读取数据
                    d1 = this.memory.zpgReadByte(addr);
                    d1++;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                //INC oper,X 零页X变址
                case 0xf6:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    //零页读取数据
                    d1 = this.memory.zpgReadByte(addr);
                    d1++;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                //INC oper 绝对寻址
                case 0xee:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.readWord(this.register.nextPC());
                    //零页读取数据
                    d1 = this.memory.read(addr);
                    d1++;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.write(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // INC oper, 绝对寻址X
                case 0xfe:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getX();
                    //整页读取数据
                    d1 = this.memory.read(addr);
                    d1++;
                    d1 &= 0xff;
                    //整页写入数据
                    this.memory.write(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // INX
                case 0xe8:
                    d1 = this.register.getX();
                    d1++;
                    d1 &= 0xff;
                    this.register.setX(d1);
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // INY
                case 0xc8:
                    d1 = this.register.getY();
                    d1++;
                    d1 &= 0xff;
                    this.register.setY(d1);
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                //DEX
                case 0xca:
                    d1 = this.register.getX();
                    d1--;
                    d1 &= 0xff;
                    this.register.setX(d1);
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                //DEY
                case 0x88:
                    d1 = this.register.getY();
                    d1--;
                    d1 &= 0xff;
                    this.register.setY(d1);
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                //DEC oper
                case 0xc6:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.read(this.register.getPC());
                    //零页读取数据
                    d1 = this.memory.zpgReadByte(addr);
                    d1--;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // Dec oper,x 
                case 0xd6:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    //零页读取数据
                    d1 = this.memory.zpgReadByte(addr);
                    d1--;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // dec oper
                case 0xce:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.readWord(this.register.nextPC());
                    //零页读取数据
                    d1 = this.memory.zpgReadByte(addr);
                    d1--;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // dec oper,x
                case 0xde:
                    //指针移到oper上
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getX();
                    //零页读取数据
                    d1 = this.memory.zpgReadByte(addr);
                    d1--;
                    d1 &= 0xff;
                    //零页写入数据
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZC(d1);
                    this.register.incPC();
                    break;
                // SBC #oper
                case 0xe9:
                    // PC 寄存器加1
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    // 对此数求补
                    d1 = this.complement(d1);
                    statusC = this.register.STATUS.getC();
                    regA = this.register.getA();
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                // SBC oper
                case 0xe5:
                    this.register.incPC();
                    //得到零页寻址的地址
                    addr = this.memory.read(this.register.getPC());
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //求补码
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                //SBC oper,x
                case 0xf5:
                    this.register.incPC();
                    //得到零页寻址的地址
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //求补码
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                // SBC oper 绝对寻址
                case 0xed:
                    this.register.incPC();
                    //得到绝对寻址的地址
                    addr = this.memory.readWord(this.register.nextPC());
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //求补码
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                case 0xfd:
                    this.register.incPC();
                    //得到绝对寻址的地址
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getX();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //求补码
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                case 0xf9:
                    this.register.incPC();
                    //得到绝对寻址的地址
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getY();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr & 0xff);
                    //求补码
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    //配置结果影响的标志位
                    break;
                // SBC (oper,x)
                case 0xe1:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //获取真实物理地址
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    addr = this.memory.zpgReadWord(addr);
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                //SBC (oper),Y
                case 0xf1:
                    //将指针指向指令的下一个地址
                    this.register.incPC();
                    //获得真实地址
                    addr = this.memory.read(this.register.getPC());
                    addr = this.memory.zpgReadWord(addr) + this.register.getY();
                    //得到此地址存储的值
                    d1 = this.memory.read(addr);
                    d1 = this.complement(d1);
                    //得到进位标志位
                    statusC = this.register.STATUS.getC();
                    //得到寄存器A的值
                    regA = this.register.getA();
                    //求和计算
                    result = regA + statusC + d1;
                    //设置负数、进位、零标志位
                    this.register.STATUS.setNZC(result);
                    //设置溢出标志位
                    if ((((regA ^ d1) & 0x80) == 0) && (((result ^ regA) & 0x80) != 0)) {
                        //溢出了此时
                        this.register.STATUS.setV(true);
                    } else {
                        this.CLV();
                    }
                    //结果放到寄存器A中
                    this.register.setA(result);
                    //PC寄存器加1，取下一条指令
                    this.register.incPC();
                    break;
                // AND #oper
                case 0x29:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // AND oper
                case 0x25:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // AND oper,x
                case 0x35:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // AND oper 绝对型
                case 0x2d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // And oper,x 绝对型
                case 0x3d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getX();
                    d1 = this.memory.read(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // And oper,y 绝对型
                case 0x39:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // AND (oper,x)
                case 0x21:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC()) + this.register.getY();
                    addr = this.memory.zpgReadWord(addr);
                    d1 = this.memory.read(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // AND (oper),y
                case 0x31:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = this.memory.zpgReadWord(addr) + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = d1 & this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                //EOR #oper
                case 0x49:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // EOR oper 零页
                case 0x45:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                //EOR oper,x
                case 0x55:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // EOR oper 绝对型
                case 0x4d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // EOR oper,x 绝对型
                case 0x5d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.read(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // EOR oper,y绝对型
                case 0x59:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // EOR (oper,x) 变址间接寻址
                case 0x41:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    addr = this.memory.zpgReadWord(addr);
                    d1 = this.memory.read(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // Eor (oper),y
                case 0x51:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = this.memory.zpgReadWord(addr) + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = d1 ^ this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // ORA #oper  逻辑或操作
                case 0x09:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x05:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x15:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x0d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x1d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.read(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x19:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x01:
                    this.register.incPC();

                    //变址
                    addr = this.memory.read(this.register.getPC()) + this.register.getX();
                    //间接寻址
                    addr = this.memory.zpgReadWord(addr);
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                case 0x11:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    //间接变址寻址
                    addr = this.memory.zpgReadWord(addr) + this.register.getY();
                    d1 = this.memory.zpgReadByte(addr);
                    result = d1 | this.register.getA();
                    this.register.STATUS.setNZC(result);
                    this.register.setA(result);
                    this.register.incPC();
                    break;
                // bit oper  零页寻址
                case 0x24:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.STATUS.setZ(!(d1 & this.register.getA()) ? true : false);
                    this.register.STATUS.setN(d1 & 0x80 ? true : false);
                    this.register.STATUS.setV(d1 & 0x40 ? true : false);
                    this.register.incPC();
                    break;
                //bit oper  绝对寻址
                case 0x2c:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    this.register.STATUS.setZ(!(d1 & this.register.getA()) ? true : false);
                    this.register.STATUS.setN(d1 & 0x80 ? true : false);
                    this.register.STATUS.setV(d1 & 0x40 ? true : false);
                    this.register.incPC();
                    break;
                // ASL
                case 0x0a:
                    //最高位送进位
                    this.register.STATUS.setC(this.register.getA() & 0x80 ? true : false)
                    //左移1位
                    this.register.setA((this.register.getA() << 1) & 0xff);
                    //置标志位
                    this.register.STATUS.setNZ(this.register.getA());
                    this.register.incPC();
                    break;
                // ASL oper
                case 0x06:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    //读内存
                    d1 = this.memory.zpgReadByte(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    //左移1位
                    d1 = (d1 << 1) & 0xff;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //asl oper,x
                case 0x16:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    //读内存
                    d1 = this.memory.zpgReadByte(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    //左移1位
                    d1 = (d1 << 1) & 0xff;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // asl oper 绝对型
                case 0x0e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    //读内存
                    d1 = this.memory.read(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    //左移1位
                    d1 = (d1 << 1) & 0xff;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // asl oper,x 绝对型
                case 0x1e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    //读内存
                    d1 = this.memory.read(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    //左移1位
                    d1 = (d1 << 1) & 0xff;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //LSR
                case 0x4a:
                    //最高位送进位
                    this.register.STATUS.setC(this.register.getA() & 0x01 ? true : false)
                    //无符号右移1位  左边补0
                    this.register.setA((this.register.getA() >>> 1) & 0xff);
                    //置标志位
                    this.register.STATUS.setNZ(this.register.getA());
                    this.register.incPC();
                    break;
                //LSR oper
                case 0x46:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    //读内存
                    d1 = this.memory.zpgReadByte(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x01 ? true : false)
                    //右移1位
                    d1 = d1 >>> 1;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x56:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    //读内存
                    d1 = this.memory.zpgReadByte(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x01 ? true : false)
                    //右移1位
                    d1 = d1 >>> 1;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x4e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    //读内存
                    d1 = this.memory.read(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x01 ? true : false)
                    //右移1位
                    d1 = d1 >>> 1;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x5e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    //读内存
                    d1 = this.memory.read(addr);
                    //最高位送进位
                    this.register.STATUS.setC(d1 & 0x01 ? true : false)
                    //右移1位
                    d1 = d1 >>> 1;
                    //写内存
                    this.memory.zpgWriteByte(addr, d1);
                    //置标志位
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // ROL 循环左移
                case 0x2a:
                    statusC = this.register.STATUS.getC() ? 1 : 0;
                    this.register.STATUS.setC(this.register.getA() & 0x80 ? true : false)
                    this.register.setA(((this.register.getA() << 1) | statusC) & 0xff);
                    this.register.STATUS.setNZ(this.register.getA());
                    this.register.incPC();
                    break;
                // ROL oper
                case 0x26:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    statusC = this.register.STATUS.getC() ? 1 : 0;
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    d1 = ((d1 << 1) | statusC) & 0xff;
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // ROl oper,x
                case 0x36:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    statusC = this.register.STATUS.getC() ? 1 : 0;
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    d1 = ((d1 << 1) | statusC) & 0xff;
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x2e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    statusC = this.register.STATUS.getC() ? 1 : 0;
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    d1 = ((d1 << 1) | statusC) & 0xff;
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x3e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.read(addr);
                    statusC = this.register.STATUS.getC() ? 1 : 0;
                    this.register.STATUS.setC(d1 & 0x80 ? true : false)
                    d1 = ((d1 << 1) | statusC) & 0xff;
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //ROR
                case 0x6a:
                    statusC = this.register.STATUS.getC();
                    statusC = statusC << 7;
                    this.register.STATUS.setC(this.register.getA() & 0x01 ? true : false);
                    this.register.setA((this.register.getA() >>> 1) | statusC);
                    this.register.STATUS.setNZ(this.register.getA());
                    this.register.incPC();
                    break;
                //ror oper
                case 0x66:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    statusC = this.register.STATUS.getC();
                    statusC = statusC << 7;
                    this.register.STATUS.setC(d1 & 0x01 ? true : false);
                    d1 = (d1 >>> 1) | statusC;
                    this.memory.write(this.register.getPC(), d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x76:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    statusC = this.register.STATUS.getC();
                    statusC = statusC << 7;
                    this.register.STATUS.setC(d1 & 0x01 ? true : false);
                    d1 = (d1 >>> 1) | statusC;
                    this.memory.write(this.register.getPC(), d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x6e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    statusC = this.register.STATUS.getC();
                    statusC = statusC << 7;
                    this.register.STATUS.setC(d1 & 0x01 ? true : false);
                    d1 = (d1 >>> 1) | statusC;
                    this.memory.write(this.register.getPC(), d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                case 0x7e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr) + this.register.getX();
                    statusC = this.register.STATUS.getC();
                    statusC = statusC << 7;
                    this.register.STATUS.setC(d1 & 0x01 ? true : false);
                    d1 = (d1 >>> 1) | statusC;
                    this.memory.write(this.register.getPC(), d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //BCC oper
                case 0x90:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (!this.register.STATUS.getC()) {
                        this.nearJump(addr);
                    }
                    break;
                // bcs oper
                case 0xb0:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (this.register.STATUS.getC()) {
                        this.nearJump(addr);
                    }
                    break;
                // beq oper
                case 0xf0:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (this.register.STATUS.getZ()) {
                        this.nearJump(addr);
                    }
                    break;
                // bne oper
                case 0xd0:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (!this.register.STATUS.getZ()) {
                        this.nearJump(addr);
                    }
                    break;
                // bmi oper
                case 0x30:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (this.register.STATUS.getN()) {
                        this.nearJump(addr);
                    }
                    break;
                //bpl oper
                case 0x10:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (!this.register.STATUS.getN()) {
                        this.nearJump(addr);
                    }
                    break;
                //BVC oper
                case 0x50:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (!this.register.STATUS.getV()) {
                        this.nearJump(addr);
                    }
                    break;
                // BVS oper
                case 0x70:
                    this.register.incPC();
                    addr = this.memory.read(this.register.nextPC());
                    if (this.register.STATUS.getV()) {
                        this.nearJump(addr);
                    }
                    break;
                // BRK
                case 0x00:
                    //未实现
                    break;
                case 0x4c:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    this.register.setPC(addr);
                    this.register.incPC();
                    break;
                case 0x6c:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = this.memory.readWord(addr);
                    this.register.setPC(addr);
                    this.register.incPC();
                    break;
                //PHA
                case 0x48:
                    if (this.push(this.register.getA())) {
                        console.log("PHA 成功")
                    } else {
                        console.log("PHA 失败")
                    }
                    this.register.incPC();
                    break;
                // PHP
                case 0x08:
                    if (this.push(this.register.STATUS.getFlag())) {
                        console.log("PHP 成功")
                    } else {
                        console.log("PHP 失败")
                    }
                    this.register.incPC();
                    break;
                //PLA
                case 0x68:
                    result = this.pop();
                    if (result != undefined) {
                        this.register.setA(result);
                        this.register.STATUS.setNZ(result);
                        console.log("PLA 成功")
                    }
                    this.register.incPC();
                    break;
                //PLP
                case 0x28:
                    result = this.pop();
                    if (result != undefined) {
                        this.register.STATUS.setFlag(result);
                        this.register.STATUS.setNZ(result);
                        console.log("PLA 成功")
                    }
                    this.register.incPC();
                    break;
                //TYA
                case 0x98:
                    this.register.setA(this.register.getY());
                    this.register.STATUS.setNZ(this.register.getA())
                    this.register.incPC();
                    break;
                //TXS
                case 0x9a:
                    this.register.setSP(this.register.getX());
                    this.register.incPC();
                    break;
                //TXA
                case 0x8a:
                    this.register.setA(this.register.getX());
                    this.register.STATUS.setNZ(this.register.getA())
                    this.register.incPC();
                    break;
                //TSX
                case 0xba:
                    this.register.setX(this.register.getSP());
                    this.register.STATUS.setNZ(this.register.getX())
                    this.register.incPC();
                    break;
                //TAY
                case 0xa8:
                    this.register.setY(this.register.getA());
                    this.register.STATUS.setNZ(this.register.getY())
                    this.register.incPC();
                    break;
                //TAX
                case 0xaa:
                    this.register.setX(this.register.getA());
                    this.register.STATUS.setNZ(this.register.getX())
                    this.register.incPC();
                    break;
                //NOP
                case 0xea:
                    //NOP
                    break;
                //LDA #oper
                case 0xa9:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDA oper
                case 0xa5:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDA oper,x
                case 0xb5:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //LDA oper绝对型
                case 0xad:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //LDA oper,x绝对型
                case 0xbd:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.read(addr);
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //LDA oper,y绝对型
                case 0xb9:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getY();
                    d1 = this.memory.read(addr);
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDA (oper,x)
                case 0xa1:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    addr = this.memory.zpgReadWord(addr);
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDA (oper),y
                case 0xb1:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = this.memory.zpgReadWord(addr);
                    addr = addr + this.register.getY();
                    this.register.setA(d1);
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDX #oper
                case 0xa2:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    this.register.setX(d1)
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDX oper
                case 0xa6:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.setX(d1)
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDX oper,y
                case 0xb6:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getY();
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.setX(d1)
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDX oper 绝对
                case 0xae:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.setX(d1)
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                // LDX oper,y
                case 0xbe:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getY();
                    d1 = this.memory.zpgReadByte(addr);
                    this.register.setX(d1)
                    this.register.STATUS.setNZ(d1);
                    this.register.incPC();
                    break;
                //sta oper
                case 0x85:
                    this.register.incPC();
                    addr = this.memory.zpgReadByte(this.register.getPC());
                    this.memory.zpgWriteByte(addr, this.register.getA());
                    this.register.incPC();
                    break;
                // sta oper,x
                case 0x95:
                    this.register.incPC();
                    addr = this.memory.zpgReadByte(this.register.getPC());
                    addr = addr + this.register.getX();
                    this.memory.zpgWriteByte(addr, this.register.getA());
                    this.register.incPC();
                    break;
                //sta oper 绝对型
                case 0x8d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    this.memory.write(addr, this.register.getA());
                    this.register.incPC();
                    break;
                // sta oper,x
                case 0x9d:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    this.memory.write(addr, this.register.getA());
                    this.register.incPC();
                    break;
                // sta oper,y
                case 0x99:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getY();
                    this.memory.write(addr, this.register.getA());
                    this.register.incPC();
                    break;
                //sta (oper,x)
                case 0x81:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    addr = this.memory.readWord(addr);
                    this.memory.write(addr, this.register.getA());
                    this.register.incPC();
                    break;
                //sta (oper),y
                case 0x91:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = this.memory.readWord(addr);
                    addr = addr + this.register.getY();
                    this.memory.write(addr, this.register.getA());
                    this.register.incPC();
                    break;
                // stx oper
                case 0x86:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    this.memory.zpgWriteByte(addr, this.register.getX());
                    this.register.incPC();
                    break;
                //stx oper,y
                case 0x96:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    this.memory.zpgWriteByte(addr, this.register.getX());
                    this.register.incPC();
                    break;
                //stx oper 绝对型
                case 0x8e:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    this.memory.write(addr, this.register.getX());
                    this.register.incPC();
                    break;
                //sty oper
                case 0x84:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    this.memory.zpgWriteByte(addr, this.register.getY());
                    this.register.incPC();
                    break;
                // sty oper,x
                case 0x94:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    this.memory.zpgWriteByte(addr, this.register.getY());
                    this.register.incPC();
                    break;
                // sty oper
                case 0x8c:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    this.memory.write(addr, this.register.getY());
                    this.register.incPC();
                    break;
                // cmp #oper
                case 0xc9:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp oper
                case 0xc5:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp oper,x
                case 0xd5:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.zpgReadByte(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp oper 绝对型
                case 0xcd:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp oper,x 绝对型
                case 0xdd:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getX();
                    d1 = this.memory.read(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp oper,y 绝对型
                case 0xd9:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    addr = addr + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp (oper,x)
                case 0xc1:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = addr + this.register.getX();
                    addr = this.memory.readWord(addr);
                    d1 = this.memory.read(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cmp (oper),x
                case 0xd1:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    addr = this.memory.readWord(addr);
                    addr = addr + this.register.getY();
                    d1 = this.memory.read(addr);
                    result = this.register.getA() - d1;
                    if (this.register.getA() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cpx  #oper
                case 0xe0:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    result = this.register.getX() - d1;
                    if (this.register.getX() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cpx oper 零页
                case 0xe4:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr)
                    result = this.register.getX() - d1;
                    if (this.register.getX() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cpx oper 绝对型
                case 0xec:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr)
                    result = this.register.getX() - d1;
                    if (this.register.getX() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cpy #oper
                case 0xc0:
                    this.register.incPC();
                    d1 = this.memory.read(this.register.getPC());
                    result = this.register.getY() - d1;
                    if (this.register.getY() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cpy oper
                case 0xc4:
                    this.register.incPC();
                    addr = this.memory.read(this.register.getPC());
                    d1 = this.memory.zpgReadByte(addr);
                    result = this.register.getY() - d1;
                    if (this.register.getY() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;
                // cpy oper 绝对型
                case 0xcc:
                    this.register.incPC();
                    addr = this.memory.readWord(this.register.nextPC());
                    d1 = this.memory.read(addr);
                    result = this.register.getY() - d1;
                    if (this.register.getY() >= d1) {
                        this.register.STATUS.setC(true);
                    } else {
                        this.register.STATUS.setC(false);
                    }
                    this.register.STATUS.setNZ(result);
                    break;

                default:


            }
        }

    }




}